HAL FMC SRAM initialization and configuration functions migration

The goal of this page is to show how to migrate the initialization sequence using STM32CubeMX2:

  • Open STM32CubeMX2 FMC SRAM configuration panel.

  • Configure the SW layer HAL.

  • Configure the FMC SRAM main features.

  • Configure the FMC SRAM advanced features.

  • Configure the FMC SRAM security and privilege features if needed.

  • Configure the FMC SRAM GPIO pins.

  • Generate the code.

Note

There is four configurations that can be done in HAL FMC SRAM:

  • Asynchronous memory HAL_SRAM_SetConfigRdWrAsyncMemory(), with an optional configuration to set different timings for write operations when needed using HAL_SRAM_SetWrAsyncTimings().

  • Synchronous memory HAL_SRAM_SetConfigRdWrSyncMemory().

  • Synchronous/Asynchronous memory HAL_SRAM_SetConfigRdSyncWrAsyncMemory().

  • Asynchronous/Synchronous memory HAL_SRAM_SetConfigRdAsyncWrSyncMemory().

The instance have been changed from bank in HAL1 to sub-bank in HAL2.

HAL FMC SRAM configuration panel

Create a new project with STM32CubeMX2, start by enabling the FMC instance as SRAM/PSRAM, as shown in this example with the selected FMC-NOR_PSRAM1, then start the initialization and the main configuration.

Project configuration panel

HAL FMC SRAM main features configuration

Configure the FMC SRAM main features.

FMC SRAM main feature configuration

HAL FMC SRAM advanced features configuration

Configure the advanced FMC SRAM features.

FMC SRAM advanced feature configuration

HAL FMC SRAM security and privilege features configuration

Configure the FMC SRAM security and privilege features if needed.

FMC SRAM security and privilege feature configuration

GPIO configuration

Configure GPIO pins.

FMC SRAM GPIO configuration

Generated SRAM initialization and de-initialization sequences

The FMC SRAM initialization and de-initialization sequences are generated in the mx_fmc_nor_psram1_sram_init function in mx_fmc.c file under $YOUR_PROJECT_NAME$/$YOUR_PROJECT_NAME$_SW/generated/STM32Cube_CodeGen.

Related concepts:

Note

Example: This configuration is reserved to STM32U5 (Specific Pins)

STM32CubeMX2 Generated : SRAM initialization and de-initialization sequences

Topic

HAL1 code snippet

HAL2 code snippet

Handle declaration

SRAM_HandleTypeDef hsram1;


GPIO_InitTypeDef GPIO_InitStruct ={0};
hal_sram_handle_t hNOR_PSRAM1;
hal_sram_config_t sram_config;
hal_sram_rd_wr_async_memory_config_t p_config;
hal_gpio_config_t  gpio_config;

Initialization and configuration sequence

/* FMC initialization function */
static void MX_FMC_Init(void)
{

  FMC_NORSRAM_TimingTypeDef Timing = {0};

  /** Perform the SRAM1 memory initialization sequence
  */
  hsram1.Instance = FMC_NORSRAM_DEVICE;
  hsram1.Extended = FMC_NORSRAM_EXTENDED_DEVICE;
  hsram1.Init.NSBank = FMC_NORSRAM_BANK1;
  hsram1.Init.DataAddressMux = FMC_DATA_ADDRESS_MUX_DISABLE;
  hsram1.Init.MemoryType = FMC_MEMORY_TYPE_SRAM;
  hsram1.Init.MemoryDataWidth = FMC_NORSRAM_MEM_BUS_WIDTH_8;
  hsram1.Init.BurstAccessMode = FMC_BURST_ACCESS_MODE_DISABLE;
  hsram1.Init.WaitSignalPolarity = FMC_WAIT_SIGNAL_POLARITY_LOW;
  hsram1.Init.WaitSignalActive = FMC_WAIT_TIMING_BEFORE_WS;
  hsram1.Init.WriteOperation = FMC_WRITE_OPERATION_ENABLE;
  hsram1.Init.WaitSignal = FMC_WAIT_SIGNAL_DISABLE;
  hsram1.Init.ExtendedMode = FMC_EXTENDED_MODE_DISABLE;
  hsram1.Init.AsynchronousWait = FMC_ASYNCHRONOUS_WAIT_ENABLE;
  hsram1.Init.WriteBurst = FMC_WRITE_BURST_DISABLE;
  hsram1.Init.ContinuousClock = FMC_CONTINUOUS_CLOCK_SYNC_ONLY;
  hsram1.Init.WriteFifo = FMC_WRITE_FIFO_DISABLE;
  hsram1.Init.NBLSetupTime = 0;
  hsram1.Init.PageSize = FMC_PAGE_SIZE_NONE;
  hsram1.Init.MaxChipSelectPulse = DISABLE;
  /* Timing */
  Timing.AddressSetupTime = 3;
  Timing.AddressHoldTime = 1;
  Timing.DataSetupTime = 3;
  Timing.DataHoldTime = 1;
  Timing.BusTurnAroundDuration = 1;
  Timing.CLKDivision = 2;
  Timing.DataLatency = 2;
  Timing.AccessMode = FMC_ACCESS_MODE_A;
  /* ExtTiming */

  if (HAL_SRAM_Init(&hsram1, &Timing, NULL) != HAL_OK)
  {
    Error_Handler( );
  }

}

static void HAL_FMC_MspInit(void){

  if (FMC_Initialized) {
    return;
  }
  FMC_Initialized = 1;

  __HAL_RCC_FMC_CLK_ENABLE();

  GPIO_InitStruct.Pin = GPIO_PIN_2 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_3  | GPIO_PIN_6 | GPIO_PIN_10 | GPIO_PIN_9 | \
                        GPIO_PIN_8  | GPIO_PIN_14 | GPIO_PIN_7 | GPIO_PIN_13 | GPIO_PIN_11 |GPIO_PIN_15 | GPIO_PIN_12;

  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
  HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

  GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_0 | GPIO_PIN_4|GPIO_PIN_7  | GPIO_PIN_3 | GPIO_PIN_5 | GPIO_PIN_1 | \
                        GPIO_PIN_14  | GPIO_PIN_15 | GPIO_PIN_12 | GPIO_PIN_10 | GPIO_PIN_13  | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_11;

  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
  HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

  GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_5  | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_12 | \
                        GPIO_PIN_14 |GPIO_PIN_13 | GPIO_PIN_15;

  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
  HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);

  GPIO_InitStruct.Pin = GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_0 | GPIO_PIN_3 | GPIO_PIN_5 | GPIO_PIN_2;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
  HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);

}

void HAL_SRAM_MspInit(SRAM_HandleTypeDef* hsram)
{
  HAL_FMC_MspInit();
}

static void MX_GPIO_Init(void)
{

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOE_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOF_CLK_ENABLE();
  __HAL_RCC_GPIOG_CLK_ENABLE();

}
hal_sram_handle_t *mx_fmc_nor_psram1_sram_init(void)
{

  if (HAL_SRAM_Init(&hNOR_PSRAM1, HAL_SRAM1) != HAL_OK)
  {
    return NULL;
  }

  HAL_RCC_FMC_EnableClock();

  sram_config.memory_type          = HAL_SRAM_MEMORY_TYPE_SRAM;
  sram_config.wait_signal_polarity = HAL_SRAM_WAIT_SIGNAL_POLARITY_LOW;

  if (HAL_SRAM_SetConfig(&hNOR_PSRAM1, &sram_config) != HAL_OK)
  {
    return NULL;
  }

  /* Asynchronous read and write with identical timing for both operation */

  p_config.memory.data_bus_width                        = HAL_SRAM_DATA_BUS_WIDTH_8_BIT;
  p_config.memory.cram_page_size_byte                   = HAL_SRAM_CRAM_PAGE_SIZE_NONE;
  p_config.memory.mux_data_addr                         = HAL_SRAM_MUX_DATA_ADDR_DISABLE;
  p_config.memory.byte_lane_setup_cycle                 = HAL_SRAM_BYTE_LANE_SRC_CLK_0_CYCLE;
  p_config.memory.psram_chipsel_maxpulse_nsec           = 20;
  p_config.timings.async_access_timings.addr_setup_nsec = 10;
  p_config.timings.async_access_timings.addr_hold_nsec  = 20;
  p_config.timings.async_access_timings.data_setup_nsec = 20;
  p_config.timings.async_access_timings.data_hold_nsec  = 10;
  p_config.timings.async_wait                           = HAL_SRAM_ASYNC_WAIT_SIGNAL_DISABLE;
  p_config.timings.bus_turnaround_nsec                  = 10;

  if (HAL_SRAM_SetConfigRdWrAsyncMemory(&hNOR_PSRAM1, &p_config) != HAL_OK)
  {
    return NULL;
  }

  HAL_SRAM_EnableMemory(&hNOR_PSRAM1);

  HAL_RCC_GPIOC_EnableClock();

  HAL_RCC_GPIOD_EnableClock();

  HAL_RCC_GPIOA_EnableClock();

  HAL_RCC_GPIOB_EnableClock();


  gpio_config.mode        = HAL_GPIO_MODE_ALTERNATE;
  gpio_config.output_type = HAL_GPIO_OUTPUT_PUSHPULL;
  gpio_config.pull        = HAL_GPIO_PULL_NO;
  gpio_config.speed       = HAL_GPIO_SPEED_FREQ_LOW;
  gpio_config.alternate   = HAL_GPIO_AF_12;
  HAL_GPIO_Init(HAL_GPIOC, HAL_GPIO_PIN_1 | HAL_GPIO_PIN_2 | HAL_GPIO_PIN_3 | \
                           HAL_GPIO_PIN_4 | HAL_GPIO_PIN_5, &gpio_config);

  gpio_config.mode        = HAL_GPIO_MODE_ALTERNATE;
  gpio_config.output_type = HAL_GPIO_OUTPUT_PUSHPULL;
  gpio_config.pull        = HAL_GPIO_PULL_NO;
  gpio_config.speed       = HAL_GPIO_SPEED_FREQ_LOW;
  gpio_config.alternate   = HAL_GPIO_AF_12;
  HAL_GPIO_Init(HAL_GPIOD, HAL_GPIO_PIN_12, &gpio_config);

  gpio_config.mode        = HAL_GPIO_MODE_ALTERNATE;
  gpio_config.output_type = HAL_GPIO_OUTPUT_PUSHPULL;
  gpio_config.pull        = HAL_GPIO_PULL_NO;
  gpio_config.speed       = HAL_GPIO_SPEED_FREQ_LOW;
  gpio_config.alternate   = HAL_GPIO_AF_10;
  HAL_GPIO_Init(HAL_GPIOD, HAL_GPIO_PIN_8 | HAL_GPIO_PIN_9, &gpio_config);

  gpio_config.mode        = HAL_GPIO_MODE_ALTERNATE;
  gpio_config.output_type = HAL_GPIO_OUTPUT_PUSHPULL;
  gpio_config.pull        = HAL_GPIO_PULL_NO;
  gpio_config.speed       = HAL_GPIO_SPEED_FREQ_LOW;
  gpio_config.alternate   = HAL_GPIO_AF_12;
  HAL_GPIO_Init(HAL_GPIOA, HAL_GPIO_PIN_12 | HAL_GPIO_PIN_11 | HAL_GPIO_PIN_10 | \
                           HAL_GPIO_PIN_9 | HAL_GPIO_PIN_2 | HAL_GPIO_PIN_1 | HAL_GPIO_PIN_0 | HAL_GPIO_PIN_5, &gpio_config);

  gpio_config.mode        = HAL_GPIO_MODE_ALTERNATE;
  gpio_config.output_type = HAL_GPIO_OUTPUT_PUSHPULL;
  gpio_config.pull        = HAL_GPIO_PULL_NO;
  gpio_config.speed       = HAL_GPIO_SPEED_FREQ_LOW;
  gpio_config.alternate   = HAL_GPIO_AF_10;
  HAL_GPIO_Init(HAL_GPIOB, HAL_GPIO_PIN_0, &gpio_config);

  gpio_config.mode        = HAL_GPIO_MODE_ALTERNATE;
  gpio_config.output_type = HAL_GPIO_OUTPUT_PUSHPULL;
  gpio_config.pull        = HAL_GPIO_PULL_NO;
  gpio_config.speed       = HAL_GPIO_SPEED_FREQ_LOW;
  gpio_config.alternate   = HAL_GPIO_AF_7;
  HAL_GPIO_Init(HAL_GPIOB, HAL_GPIO_PIN_1, &gpio_config);

  gpio_config.mode        = HAL_GPIO_MODE_ALTERNATE;
  gpio_config.output_type = HAL_GPIO_OUTPUT_PUSHPULL;
  gpio_config.pull        = HAL_GPIO_PULL_NO;
  gpio_config.speed       = HAL_GPIO_SPEED_FREQ_LOW;
  gpio_config.alternate   = HAL_GPIO_AF_12;
  HAL_GPIO_Init(HAL_GPIOB, HAL_GPIO_PIN_2, &gpio_config);

  return &hNOR_PSRAM1;
}

Deinitialization sequence

static void HAL_FMC_MspDeInit(void)
{
  if (FMC_DeInitialized) {
    return;
  }
  FMC_DeInitialized = 1;
  /* Peripheral clock enable */
  __HAL_RCC_FMC_CLK_DISABLE();

  HAL_GPIO_DeInit(GPIOD, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_7 | GPIO_PIN_8 | \
                         GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 |GPIO_PIN_14 | GPIO_PIN_15);


  HAL_GPIO_DeInit(GPIOE, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_3 | GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 | \
                         GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15);

  HAL_GPIO_DeInit(GPIOF, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | \
                         GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15);


  HAL_GPIO_DeInit(GPIOG, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_12);
}

void HAL_SRAM_MspDeInit(SRAM_HandleTypeDef* hsram)
{
  HAL_FMC_MspDeInit();
}

static void MX_FMC_DeInit(void)
{
  /* Deinitialize the SRAM peripheral */
  if (HAL_SRAM_DeInit(&hsram1) != HAL_OK)
  {
    Error_Handler();
  }
}
void mx_fmc_nor_psram1_sram_deinit(void)
{
  /* De-initialize all GPIO pins associated with FMC */
  HAL_GPIO_DeInit(HAL_GPIOC, HAL_GPIO_PIN_1 | HAL_GPIO_PIN_2 | HAL_GPIO_PIN_3 | HAL_GPIO_PIN_4 | HAL_GPIO_PIN_5);

  HAL_GPIO_DeInit(HAL_GPIOD, HAL_GPIO_PIN_8 | HAL_GPIO_PIN_9 | HAL_GPIO_PIN_12);

  HAL_GPIO_DeInit(HAL_GPIOA, HAL_GPIO_PIN_0 | HAL_GPIO_PIN_1 | HAL_GPIO_PIN_2 | \
                             HAL_GPIO_PIN_5 | HAL_GPIO_PIN_9 | HAL_GPIO_PIN_10 | HAL_GPIO_PIN_11 | HAL_GPIO_PIN_12);

  HAL_GPIO_DeInit(HAL_GPIOB, HAL_GPIO_PIN_0 | HAL_GPIO_PIN_1 | HAL_GPIO_PIN_2);

  HAL_SRAM_DeInit(&hNOR_PSRAM1);
}

All subbanks configuration

HAL1 code snippet

HAL2 code snippet

SRAM_HandleTypeDef hsram[4] = {hsram1, hsram2, hsram3, hsram4};

uint32_t sram_instance[4] = {FMC_NORSRAM_BANK1, FMC_NORSRAM_BANK2, FMC_NORSRAM_BANK3, FMC_NORSRAM_BANK4};


HAL_Init();

// --- SRAM bank (1) and sub-banks Initialization SRAMx (x = 1 to 4) ---
for (int i = 0; i < 4; i++)
{
   hsram[i].Instance = FMC_NORSRAM_DEVICE;
   hsram[i].Extended = FMC_NORSRAM_EXTENDED_DEVICE;
   hsram[i].Init.NSBank             = sram_instance[i];
   hsram[i].Init.DataAddressMux     = FMC_DATA_ADDRESS_MUX_DISABLE;
   hsram[i].Init.WriteOperation     = FMC_WRITE_OPERATION_ENABLE;
   hsram[i].Init.BurstAccessMode    = FMC_BURST_ACCESS_MODE_DISABLE;
   hsram[i].Init.WrapMode           = FMC_WRAP_MODE_DISABLE;
   hsram[i].Init.WaitSignalActive   = FMC_WAIT_TIMING_BEFORE_WS;
   hsram[i].Init.WaitSignal         = FMC_WAIT_SIGNAL_DISABLE;
   hsram[i].Init.ExtendedMode       = FMC_EXTENDED_MODE_DISABLE;
   hsram[i].Init.WriteBurst         = FMC_WRITE_BURST_DISABLE;
   hsram[i].Init.ContinuousClock    = FMC_CONTINUOUS_CLOCK_SYNC_ONLY;

   // Fill static configuration
   hsram[i].Init.MemoryType         = FMC_MEMORY_TYPE_SRAM;
   /* ---------------------------------------------------------- */
   hsram[i].Init.WaitSignalPolarity = FMC_WAIT_SIGNAL_POLARITY_LOW;

   // Fill memory configuration
   hsram[i].Init.MemoryDataWidth    = FMC_NORSRAM_MEM_BUS_WIDTH_16;

   hsram[i].Init.AsynchronousWait   = FMC_ASYNCHRONOUS_WAIT_DISABLE;
   Sram_Timing.AddressSetupTime      = 2;
   Sram_Timing.AddressHoldTime       = 1;
   Sram_Timing.DataSetupTime         = 2;
   Sram_Timing.DataHoldTime          = 1;
   Sram_Timing.BusTurnAroundDuration = 1;
   Sram_Timing.CLKDivision           = 2;
   Sram_Timing.DataLatency           = 2;

   /* Optional: Set different write timings if needed */
   Sram_Wr_Timing.AddressSetupTime   = 3;
   Sram_Wr_Timing.AddressHoldTime    = 1;
   Sram_Wr_Timing.DataSetupTime      = 3;
   Sram_Wr_Timing.DataHoldTime       = 1;
   Sram_Wr_Timing.BusTurnAroundDuration = 1;
   Sram_Wr_Timing.AccessMode            = FMC_ACCESS_MODE_A;
   HAL_SRAM_Init(&hsram[i], &Sram_Timing, &Sram_Wr_Timing);
}
hal_sram_handle_t* hsram [4] ={hsram1, hsram2, hsram3, hsram4};

hal_sram_t sram_instance[4] = {HAL_SRAM1, HAL_SRAM2, HAL_SRAM3, HAL_SRAM4};

HAL_Init();

// Initialize the SRAM handle and associate to the HAL_SRAMx instance
for (int i = 0; i < 4; i++)
{
   HAL_SRAM_Init(&hsram[i], sram_instance[i]);
}

// Fill static configuration of FMC peripheral
sram_config.memory_type = HAL_SRAM_MEMORY_TYPE_SRAM;
sram_config.write_fifo = HAL_SRAM_WRITE_FIFO_DISABLE;
sram_config.wait_signal_polarity = HAL_SRAM_WAIT_SIGNAL_POLARITY_LOW;

/* Fill memory configuration */
sram_mem_config.memory.data_width = HAL_SRAM_DATA_BUS_WIDTH_16_BIT;
sram_mem_config.memory.cram_page_size_byte = HAL_SRAM_PAGE_SIZE_NONE;
sram_mem_config.memory.mux_mode = HAL_SRAM_MUX_DATA_ADDR_DISABLE;
sram_mem_config.memory.byte_lane_setup_cycle = HAL_SRAM_BYTE_LANE_SRC_CLK_0_CYCLE;
sram_mem_config.memory.psram_chipsel_maxpulse_nsec = 0;

sram_mem_config.timings.async_wait = HAL_SRAM_ASYNC_WAIT_SIGNAL_DISABLE;
sram_mem_config.timings.async_access_timings.addr_setup_nsec = 20;
sram_mem_config.timings.async_access_timings.addr_hold_nsec = 10;
sram_mem_config.timings.async_access_timings.data_setup_nsec = 20;
sram_mem_config.timings.async_access_timings.data_hold_nsec = 10;
sram_mem_config.timings.bus_turnaround_nsec = 10;
/* ---------------------------------------------------------- */
/* ---------------------------------------------------------- */

/* Optional: Set different write timings if needed */
sram_wr_timings.async_access_timings.addr_setup_nsec = 30;
sram_wr_timings.async_access_timings.addr_hold_nsec = 10;
sram_wr_timings.async_access_timings.data_setup_nsec = 30;
sram_wr_timings.async_access_timings.data_hold_nsec = 10;
sram_wr_timings.bus_turnaround_nsec = 10;
sram_wr_timings.read_access_mode = HAL_SRAM_ACCESS_MODE_A;
sram_wr_timings.write_access_mode = HAL_SRAM_ACCESS_MODE_A;

for (int i = 0; i < 4; i++)
{
   HAL_SRAM_SetConfig(&hsram[i], &sram_config); // FMC peripheral configuration
   HAL_SRAM_SetConfigRdWrAsyncMemory(&hsram[i], &sram_mem_config); // FMC memory configuration
   HAL_SRAM_SetWrAsyncTimings(&hsram[i], &sram_wr_timings); //Optional: FMC write timing configuration when different timing needed for write operation
   HAL_SRAM_EnableMemory(&hsram[i]); // Enable the SRAM sub-bank x
}